package com.xqboss.apps.service.consumer;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.constant.Config;
import com.xqboss.apps.domain.consumer.ConsumerTeamGainRule;
import com.xqboss.apps.mapper.consumer.ConsumerTeamGainRuleMapper;
import com.xqboss.apps.vo.consumer.TeamGainRuleVo;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.system.service.ISysConfigService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 队伍增益规则表接口
 *
 * @author wangcong
 * @date 2023-08-28
 */
@Service
public class ConsumerTeamGainRuleService extends ServiceImpl<ConsumerTeamGainRuleMapper, ConsumerTeamGainRule> {

    @Resource
    private ConsumerTeamGainRuleMapper consumerTeamGainRuleMapper;

    @Autowired
    private ISysConfigService sysConfigService;//系统配置参数

    /**
     * 获取现阶段增益规则
     *
     * @param punchCount 今日打卡次数
     * @param teamRank 队伍等级
     * @return
     */
    public ConsumerTeamGainRule getPunchCountRule(long punchCount,Integer teamRank){

        // 返回小于指定打卡次数的最大打卡次数收益(争对一级的队伍)
        if(teamRank == 1){
            return getOne(new LambdaQueryWrapper<ConsumerTeamGainRule>()
                    .le(ConsumerTeamGainRule::getTotalPunch, punchCount)
                    .orderByDesc(ConsumerTeamGainRule::getTotalPunch)
                    .last("LIMIT 1"));
        }
        // 争对非一级的队伍
        List<ConsumerTeamGainRule> gainRules = getConsumerTeamGainRules(teamRank);
        // 根据今日打卡次数确定现阶段增益规则
        return gainRules.stream().filter(rule -> rule.getTotalPunch() <= punchCount).reduce((first, second) -> second).orElse(null);
    }


    /**
     * 获取下阶段增益规则
     * @param punchCount 今日打卡次数
     * @param teamRank 队伍等级
     * @return
     */
    public ConsumerTeamGainRule getNextPunchCountRule(long punchCount,Integer teamRank){
        // 返回大于指定打卡次数的最大打卡次数收益
        // 比如当前打卡次数81， 规则为60、80、100、120， 则返回100
        if(teamRank==1){
            return getOne(new LambdaQueryWrapper<ConsumerTeamGainRule>()
                    .gt(ConsumerTeamGainRule::getTotalPunch, punchCount)
                    .orderByAsc(ConsumerTeamGainRule::getTotalPunch)
                    .last("LIMIT 1"));
        }
        // 争对非一级的队伍
        List<ConsumerTeamGainRule> gainRules = getConsumerTeamGainRules(teamRank);
        // 根据今日打卡次数确定下阶段增益规则
        return gainRules.stream().filter(rule -> rule.getTotalPunch() > punchCount).findFirst().orElse(null);
    }


    public Integer delByIds(List<Long> delIds) {
        return consumerTeamGainRuleMapper.delByIds(delIds);
    }


    /**
     * 按照打卡次数从小到大排序获取打卡增益规则
     *
     * @return 打卡增益规则
     */
    private List<ConsumerTeamGainRule> getConsumerTeamGainRules() {
        List<ConsumerTeamGainRule> gainRules = this.list(new LambdaQueryWrapper<ConsumerTeamGainRule>().orderByAsc(ConsumerTeamGainRule::getTotalPunch));
        if (gainRules.isEmpty()||gainRules.size()<4) {
            throw new ServiceException("队伍增益规则不能为空，现版本需要配置4条规则!");
        }
        return gainRules;
    }

    /**
     * 按照打卡次数从小到大排序获取打卡增益规则 && 获取对应队伍等级的
     *
     * @param teamRank 队伍等级
     * @return 打卡增益规则
     */
    public List<ConsumerTeamGainRule> getConsumerTeamGainRules(Integer teamRank) {
        return getConsumerTeamGainRules(teamRank,getConsumerTeamGainRules());
    }

    /**
     * 按照打卡次数从小到大排序获取打卡增益规则 && 获取对应队伍等级的
     *
     * @param teamRank 队伍等级
     * @param gainRules 按照打卡次数从小到大排序获取打卡增益规则
     * @return 打卡增益规则
     */
    public List<ConsumerTeamGainRule> getConsumerTeamGainRules(Integer teamRank,List<ConsumerTeamGainRule> gainRules) {
        if (teamRank==1) {
            // 获取所有的增益规则(默认的规则配置都是争对一级的队伍)
            return gainRules;
        }
        int s = teamRank - 1;
        Integer totalPunch_add = this.sysConfigService.getValue(Config.Sys.Team.升级打卡次数叠加);
        BigDecimal gain_add = this.sysConfigService.getValue(Config.Sys.Team.升级增幅比例叠加);
        Integer a = totalPunch_add * s;//当前队伍等级需要叠加的打卡次数
        BigDecimal b = gain_add.multiply(new BigDecimal(s));//当前队伍等级需要叠加的增益比
        for (ConsumerTeamGainRule gainRule : gainRules) {
            gainRule.setTotalPunch(gainRule.getTotalPunch() + a);
            gainRule.setGain(gainRule.getGain().add(b).setScale(2, RoundingMode.DOWN));
        }
        return gainRules;
    }

    /**
     * 获取全队热豆增幅梯度
     *
     * @param currentRank 当前队伍等级
     * @return 全队热豆增幅梯度
     */
    public TeamGainRuleVo getTeamGainRuleVo(int currentRank) {
        // 按照打卡次数从小到大排序获取打卡增益规则
        List<ConsumerTeamGainRule> gainRules = getConsumerTeamGainRules();
        // 升级之前增益规则
        List<ConsumerTeamGainRule> nowGainRules = getConsumerTeamGainRules(currentRank, BeanUtil.copyToList(gainRules,ConsumerTeamGainRule.class));
        // 升级之后增益规则
        List<ConsumerTeamGainRule> toGainRules = getConsumerTeamGainRules(currentRank+1,BeanUtil.copyToList(gainRules,ConsumerTeamGainRule.class));
        // 返回全队热豆增幅梯度数据
        return TeamGainRuleVo.builder()
                .oneNowGain(nowGainRules.get(0).getGain())
                .oneToGain(toGainRules.get(0).getGain())
                .twoNowGain(nowGainRules.get(1).getGain())
                .twoToGain(toGainRules.get(1).getGain())
                .threeNowGain(nowGainRules.get(2).getGain())
                .threeToGain(toGainRules.get(2).getGain())
                .fourNowGain(nowGainRules.get(3).getGain())
                .fourToGain(toGainRules.get(3).getGain())
                .build();
    }

}
